/**
 * @addtogroup gbc_msg_17691
 * gbc_17691_mgr
 * @brief        国六协议管理器，保存国六协议通用部分的信息
 * @par 示例
 * @code
   // 管理器主要保存协议消息头的共用字段、数据流编解码接口和加密接口
   // TGbc17691MgrProcessData调用一次解析一条消息
   // 登入流水号从0开始，信息流水号默认从1开始，流水号需要保存在存储中，防止掉电丢失
   // 车辆VIN码长度为17字节
   // 注册的加密接口在数据流上报和防篡改备案消息的编码中使用，如果不加密则可以不实现接口
   // 数据流的编解码接口是为了兼容地标协议中数据项的不同，目前组件中实现的是山东地标协议
    
    // 实现编码事件
    static void Gbc17691DoDecode(TGbc17691Mgr *sender, void *receiver, TGbc17691MsgHead *msg_head)
    {
        printf("cmd:%d,pdu_len:%d\n", msg_head->cmd, msg_head->pdu_lenth);
        switch (msg_head->cmd)  ///< 根据消息头的命令字进入各自的处理
        {
            case kGbc17691CmdLogin: ///< 登入消息
            {
                TGbc17691MsgLogin msg_login;
                TGbc17691MsgLoginCreate(&msg_login);
                TGbc17691MsgDecode((TGbc17691Msg *)&msg_login, sender, msg_head->pdu, msg_head->pdu_lenth);
            }
            break;

            case kGbc17691CmdRecordAck: ///< 备案应答
            {
                TGbc17691MsgRecordAck record_ack;
                TGbc17691MsgRecordAckCreate(&record_ack);
                TGbc17691MsgDecode((TGbc17691Msg *)&record_ack, sender, msg_head->pdu, msg_head->pdu_lenth);
            }
            break;
        }

        return 0;
    }

    int main(int argc, char *argv[])
    {
       // 1、初始化工作，创建管理器，初始化
       TGbc17691Mgr mgr;
       TGbc17691DataStreamSdComp ds_comp; ///< 实现山东地标数据流编解码的组件
       TGbc17691MsgLogin msg_login; ///< 国六登入消息

       TGbc17691MgrCreate(&mgr, kGbc17691ProtocolSd, 1, kGbc17691ETypeNotEncrypt);
       TGbc17691MgrSetLoginSeqId(&mgr, 0); ///< 设置登入流水号，如不设置，默认从0开始
       TGbc17691MgrSetMsgSeqId(&mgr, 1); ///< 设置信息流水号，如不设置，默认从1开始
       TGbc17691MgrSetVin(&mgr, "00000002008210917", 17); ///< 设置VIN码
       TGbc17691MgrRegisterOnDecode(&mgr, NULL, Gbc17691DoDecode);  ///< 注册解码事件

       if (TGbc17691MsgProtocolType(&mgr) == kGbc17691ProtocolSd)
       {
           // 获取数据流编解码接口
           TGbc17691DataStreamSdCompCreate(&ds_comp);
           mgr.data_stream_codec = TGbc17691DataStreamSdCompInterface(&ds_comp);
       
       }

       // 2、具体消息编码
       TGbc17691MsgLoginCreate(&msg_login);
       msg_login.login_seq = TGbc17691MgrLoginSeqId(mgr, kGbc17691LoginType);
       ...///< msg_login对象其他对象赋值

       // 登录消息编码
       enc_len = TGbc17691MsgEncode((TGbc17691Msg *)&msg_login, mgr, buf, sizeof(buf));
       ...

       // 3、协议解码调用
       const char *temp = "18171323230130303030303030323030383231303931370D01001B2008292005560001333233323236363737343332333333343535386B";
       char data[256];
       Int32 len = Ascii2Hex(data, temp);
       msg_len = TGbc17691MgrProcessData(mgr, data, len, &remove_size);
       ...
   }

   TGbc17691MgrDestroy(&mgr);
 * @endcode
 * @{
 */
/**
 * @file         gbc_17691_mgr.h
 * @brief        国六协议管理器
 * @note
 * @author       dengdeshou
 * @date         2020-08-05
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2020-08-05  <td>1.0                   <td>Dengdeshou      <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _SCC_PT17691_H_
#define _SCC_PT17691_H_

#include "ofc/ofc_object.h"
#include "ofc/ofc_types.h"
#include "gbmsg17691/gbc_17691_ds_interface.h"
#include "gbmsg17691/gbc_17691_encrypt_interface.h"
#include "gbmsg17691/gbc_17691_codec.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 国六消息管理器
 */
typedef struct TGbc17691MgrTag TGbc17691Mgr;

/**
 * 国六协议类型
 */
enum TGbc17691ProtocolEnumTag
{
    kGbc17691ProtocolGb = 0x00,       ///< 国标标准协议
    kGbc17691ProtocolHj = 0x01,       ///< HJ协议
    kGbc17691ProtocolHz = 0x02,       ///< 杭州环协直连
    kGbc17691ProtocolZz = 0x03,       ///< 郑州地标
    kGbc17691ProtocolJh = 0x04,       ///< 京环
    kGbc17691ProtocolSd = 0x05,       ///< 山东地标
    kGbc17691ProtocolTsg5 = 0x06,     ///< 唐山国五
    kGbc17691ProtocolLf = 0x07,       ///< 廊坊协议
    kGbc17691ProtocolHzHtzf = 0x08,   ///< 杭州鸿途转发
    kGbc17691ProtocolMax
};
typedef enum TGbc17691ProtocolEnumTag TGbc17691ProtocolEnum;

/**
 * 国六加密方式
 */
enum TGbc17691EncryptTypeEnumTag
{
    kGbc17691ETypeNotEncrypt = 0x01,  ///< 不加密
    kGbc17691ETypeRSA = 0x02,         ///< RSA加密
    kGbc17691ETypeSM2 = 0x03,         ///< SM2加密
    kGbc17691ETypeAbnormal = 0xFE,    ///< 异常
    kGbc17691ETypeInvalid = 0xFF,     ///< 无效
};
typedef enum TGbc17691EncryptTypeEnumTag TGbc17691EncryptTypeEnum;

enum TGbc17691LogTypeTag
{
    kGbc17691LoginType = 1,
    kGbc17691LogoutType = 2,
};
typedef enum TGbc17691LogTypeTag TGbc17691LogType;

/**
 * 国六签名位置(HJ系列协议才有签名)
 */
enum TGbc17691SignatureTypeEnumTag
{
    kGbc17691SignatureSinceHeader = 0x00,  ///< 从实时消息头开始签名
    kGbc17691SignatureSkipHeader  = 0x01,  ///< 跳过实时消息头，从信息body开始签名
};
typedef enum TGbc17691SignatureTypeEnumTag TGbc17691SignatureTypeEnum;

/**
 * 解码事件
 * @param sender: TGbc17691Mgr对象指针
 * @param receiver: 接收者
 * @param msg_head: 17691消息头
 * @return
 */
typedef void(*TGbc17691DoDecode)(TGbc17691Mgr *sender, void *receiver, TGbc17691MsgHead *msg_head);

/**
 * 解码事件
 */
typedef struct TGbc17691OnDocodeTag TGbc17691OnDocode;
struct TGbc17691OnDocodeTag
{
    void *object;               ///< 对象
    TGbc17691DoDecode Method;   ///< 方法
};

/**
 * 国六协议消息管理器
 */
struct TGbc17691MgrTag
{
PROTECTED
    TGbc17691OnDocode OnDecode;               ///< 解码事件
    IGbc17691DataStream *data_stream_codec;   ///< 数据流编解码
    IGbc17691Encrypt *encrypt;                ///< 加密接口
PRIVATE
    UInt8 protocol_type_;                    ///< 协议类型，对应对标。参考TGbc17691EncryptTypeEnum
    UInt16 login_seq_id_;                    ///< 登录流水号
    UInt16 msg_seq_id_;                      ///< 信息流流水号
    Int8 vin_[17];                           ///< 车辆VIN码
    UInt8 soft_ver_;                         ///< 软件版本号
    UInt8 encrypt_type_;                     ///< 加密类型,参考 TGbc17691EncryptTypeEnum
    Bool  signature_;                        ///< 是否需要签名
};

/**
 * 国六协议框架构造函数
 * @param self: 对象指针
 * @param protocol_type: 协议类型,参考TGbc17691ProtocolEnum
 * @param soft_ver: 软件版本号
 * @param encrypt_type: 加密类型
 * @return
 */
void TGbc17691MgrCreate(TGbc17691Mgr *self, UInt8 protocol_type, UInt8 soft_ver, UInt8 encrypt_type, Bool signature);

/**
 * 析构函数
 * @param self: 对象指针
 * @return
 */
void TGbc17691MgrDestroy(TGbc17691Mgr *self);

/**
 * 创建国六消息头
 * @param self: 对象指针
 * @param cmd: 命令字
 * @param msg_head: 消息头指针
 * @return
 */
void TGbc17691MgrCreateMsgHead(TGbc17691Mgr *self, UInt8 cmd, TGbc17691MsgHead *msg_head);

/**
 * 注册消息解码事件
 * @param self: 对象指针
 * @param msg_proc_object: 解码处理事件的接收者
 * @param msg_proc_event: 解码处理事件
 * @return True: 成功; False: 失败
 */
Bool TGbc17691MgrRegisterOnDecode(TGbc17691Mgr *self, void *msg_proc_object, TGbc17691DoDecode decode_event);

/**
 * 注册数据流编解码处理
 * @param self: 对象指针
 * @param ds_codec_proc: 编解码接口
 * @return True: 成功; False: 失败
 */
//Bool TGbc17691MgrRegisterDsCodec(TGbc17691Mgr *self, IGbc17691DataStream *ds_codec_proc);

/**
 * 接口注册
 * @param self: 对象指针
 * @param ds_codec_proc: 编解码接口
 * @param gbc_encrypt: 数据加密签名接口
 * @return True: 成功; False: 失败
 */
Bool TGbc17691MgrRegisterInterface(TGbc17691Mgr *self, IGbc17691DataStream *ds_codec_proc, IGbc17691Encrypt *gbc_encrypt);

/**
 * 数据解析处理
 * @param self: 对象指针
 * @param buf: 要解析的数据缓冲区
 * @param buf_size: 数据缓冲区长度
 * @return >0为解析的消息长度，负数为错误码，参考TGbc17691ErrorCodeEnum
 */
Int32 TGbc17691MgrProcessData(TGbc17691Mgr *self, UInt8 *buf, Int32 buf_size, Int32 *remove_size);

/**
 * 设置登入流水号
 * @param self: 对象指针
 * @param login_seq: 登入流水号
 * @return
 */
void TGbc17691MgrSetLoginSeqId(TGbc17691Mgr *self, UInt16 login_seq_id);

/**
 * 获取登入流水号
 * @param self: 对象指针
 * @param log_type: 登录类型，参考TGbc17691LogType
 * @return 登入流水号
 */
UInt16 TGbc17691MgrLoginSeqId(TGbc17691Mgr *self, UInt8 log_type);

/**
 * 设置信息流水号
 * @param self: 对象指针
 * @param msg_seq: 信息流水号
 * @return
 */
void TGbc17691MgrSetMsgSeqId(TGbc17691Mgr *self, UInt16 msg_seq_id);

/**
 * 获取信息流水号
 * @param self: 对象指针
 * @return 信息流水号
 */
UInt16 TGbc17691MgrMsgSeqId(TGbc17691Mgr *self);

/**
 * 获取VIN码
 * @param self: 对象指针
 * @param buf: 存放VIN码的数据缓冲
 * @param buf_size: 缓冲区大小
 * @return VIN码长度
 */
Int32 TGbc17691MgrVin(TGbc17691Mgr *self, Int8 *buf, Int32 buf_size);

/**
 * 设置VIN码
 * @param self: 对象指针
 * @param buf: 存放VIN码的数据缓冲
 * @param buf_size: 缓冲区大小
 * @return
 */
void TGbc17691MgrSetVin(TGbc17691Mgr *self, Int8 *buf, Int32 buf_size);

/**
 * 获取软件版本号
 * @param self: 对象指针
 * @return 软件版本号
 */
UInt8 TGbc17691MgrSoftVer(TGbc17691Mgr *self);

/**
 * 设置软件版本号
 * @param self: 对象指针
 * @param soft_ver: 软件版本号
 * @return
 */
void TGbc17691MgrSetSoftVer(TGbc17691Mgr *self, UInt8 soft_ver);

/**
 * 获取加密类型
 * @param self: 对象指针
 * @return 加密类型 参考TGbc17691EncryptTypeEnum
 */
UInt8 TGbc17691MgrEncryptType(TGbc17691Mgr *self);

/**
 * 设置加密类型
 * @param self: 对象指针
 * @param encrypt_type: 加密类型,参考TGbc17691EncryptTypeEnum
 * @return
 */
void TGbc17691MgrSetEncryptType(TGbc17691Mgr *self, UInt8 encrypt_type);

/**
 * 设置是否要签名
 * @param self: 对象指针
 * @param used: 是否要签名
 * @return
 */
void TGbc17691MgrSetSignature(TGbc17691Mgr *self, Bool used);

/**
 * 获取是否需要签名
 * @param self: 对象指针
 * @return 
 */
Bool TGbc17691MgrSignature(TGbc17691Mgr *self);

/**
 * 获取国六协议地标类型
 * @param self: 对象指针
 * @return 地标类型，参考TGbc17691ProtocolEnum
 */
UInt8 TGbc17691MsgProtocolType(TGbc17691Mgr *self);

/**
 * 获取国六协议签名起始位置
 * @param self: 对象指针
 * @return 签名起始位置类型 参见@TGbc17691SignatureTypeEnum
 */
UInt8 TGbc17691MsgProtocolSignaturePositionType(TGbc17691Mgr *self);

#ifdef __cplusplus
} // extern "C" {
#endif

#endif
/**
 * @} 
 */
